﻿using Flurl.Http;
using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using SqlSugar;
using YJ_Code.Enums;
using YJ_Core.Entities.Utils;
using YJ_Core.Entities.Common;
using YJ_Core.Tool.Token;
using static YJ_App.Tool.Image.ImageDto;
using System.Text.Json;
using Aliyun.OSS;
using Microsoft.Extensions.Options;
using Aliyun.OSS.Common;

namespace YJ_App.Tool.Image
{

    /// <summary>
    /// 图片工具服务-公共（调用方式：）
    /// </summary>
    [ApiDescriptionSettings(ApiGroupEnumsCode.Tool, Name = "ImageService")]
    public class ImageService : IDynamicApiController, ITransient
    {
        /// <summary>
        /// sql
        /// </summary>
        private readonly ISqlSugarClient _db;

        private readonly HttpClient _httpClient;

        // ImgBB
        private readonly string _apiKey; // 从 ImgBB 后台获取的 API Key

        // 阿里云 OSS
        private readonly OssOptions _ossOptions;
        private readonly OssClient _ossClient;

        /// <summary>
        /// 构造函数
        /// </summary>
        public ImageService(ISqlSugarClient db, HttpClient httpClient, IConfiguration configuration, IOptions<OssOptions> ossOptions)
        {
            // imgBB
            _httpClient = httpClient;
            _apiKey = configuration["ImgBb:ApiKey"]; // 配置到 appsettings.json
            _db = db;

            // 阿里云 OSS 配置
            _ossOptions = ossOptions.Value;
            _ossClient = new OssClient(_ossOptions.Endpoint, _ossOptions.AccessKeyId, _ossOptions.AccessKeySecret);
        }

        /// <summary>
        /// 上传图片到阿里云 OSS（支持单文件和多文件）
        /// </summary>
        /// <param name="files">上传的文件列表</param>
        /// <param name="type">图片类型，用于分类存储</param>
        /// <returns>返回上传结果</returns>
        public async Task<OssUploadResponse> UploadImageOSS(List<IFormFile> files, string type = "common")
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限");

            if (files == null || files.Count == 0)
                throw Oops.Bah("请选择有效的图片文件");

            // 只处理第一个文件（保持原有接口兼容性）
            var file = files[0];
            if (file == null || file.Length == 0)
                throw Oops.Bah("请选择有效的图片文件");

            try
            {
                // 验证文件类型
                var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp" };
                var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant();
                if (!allowedExtensions.Contains(fileExtension))
                    throw Oops.Bah("不支持的文件格式，仅支持 jpg, jpeg, png, gif, bmp, webp 格式");

                // 验证文件大小（5MB）
                if (file.Length > 10 * 1024 * 1024)
                    throw Oops.Bah("文件大小不能超过 10MB");

                // 生成唯一的对象键（Object Key）
                // 格式：{type}/{yyyyMMdd}/{Guid}{扩展名}
                var uploadDate = DateTime.Now.ToString("yyyyMMdd");
                var fileName = $"{Guid.NewGuid():N}{fileExtension}";
                var objectKey = $"{type}/{uploadDate}/{fileName}";

                using var stream = file.OpenReadStream();

                // ========== 新增：设置 Content-Type ==========
                var objectMetadata = new ObjectMetadata();
                // 根据文件扩展名设置对应的 Content-Type
                switch (fileExtension)
                {
                    case ".jpg":
                    case ".jpeg":
                        objectMetadata.ContentType = "image/jpeg";
                        break;
                    case ".png":
                        objectMetadata.ContentType = "image/png";
                        break;
                    case ".gif":
                        objectMetadata.ContentType = "image/gif";
                        break;
                    case ".bmp":
                        objectMetadata.ContentType = "image/bmp";
                        break;
                    case ".webp":
                        objectMetadata.ContentType = "image/webp";
                        break;
                    default:
                        objectMetadata.ContentType = "application/octet-stream"; // 默认二进制类型
                        break;
                }

                // 上传文件到 OSS
                var putObjectResult = _ossClient.PutObject(_ossOptions.BucketName, objectKey, stream, objectMetadata);

                if (putObjectResult.HttpStatusCode == System.Net.HttpStatusCode.OK)
                {
                    // 构建访问 URL
                    string imageUrl;
                    if (!string.IsNullOrEmpty(_ossOptions.Domain))
                    {
                        // 使用自定义域名
                        imageUrl = $"{_ossOptions.Domain.TrimEnd('/')}/{objectKey}";
                    }
                    else
                    {
                        // 使用 OSS 默认域名
                        imageUrl = $"https://{_ossOptions.BucketName}.{_ossOptions.Endpoint.Replace("https://", "")}/{objectKey}";
                    }

                    // 可以在这里记录上传日志到数据库
                    //await RecordUploadLog(user.UserId, file.FileName, objectKey, imageUrl, "OSS", type);

                    return new OssUploadResponse
                    {
                        success = true,
                        url = imageUrl,
                        objectKey = objectKey,
                        message = "图片上传成功"
                    };
                }
                else
                {
                    throw Oops.Bah("图片上传失败，OSS 返回状态异常");
                }
            }
            catch (OssException ex)
            {
                // 记录详细的 OSS 异常信息
                throw Oops.Bah($"OSS 上传异常: {ex.ErrorCode} - {ex.Message}");
            }
            catch (Exception ex)
            {
                throw Oops.Bah($"图片上传失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 记录上传日志到数据库（可选）
        /// </summary>
        private async Task RecordUploadLog(string user, string originalName, string objectKey, string url, string platform, string type)
        {
            try
            {
                // 这里可以记录上传日志到数据库
                // 示例代码，根据您的实际数据库结构调整
                var log = new
                {
                    UserId = user,
                    OriginalName = originalName,
                    ObjectKey = objectKey,
                    Url = url,
                    Platform = platform,
                    Type = type,
                    UploadTime = DateTime.Now,
                    Status = "active"
                };

                // 使用 _db 插入日志记录
                // await _db.Insertable(log).ExecuteCommandAsync();
            }
            catch (Exception ex)
            {
                // 记录日志失败不影响主要功能
                Console.WriteLine($"记录上传日志失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 上传图片到ImgBB（支持单文件和多文件）
        /// </summary>
        /// <param name="files">上传的文件列表</param>
        /// <param name="type">图片类型</param>
        /// <returns>返回第一个成功上传的结果</returns>
        public async Task<ImgBBResponse> UploadImageImgBB(List<IFormFile> files, string type)
        {
            // 获取操作用户的信息
            var user = TokenService.GetClaimKey() ?? throw Oops.Bah("未登录，无权限");

            if (files == null || files.Count == 0)
                throw Oops.Bah("请选择有效的图片文件");

            // 只处理第一个文件（保持原有接口兼容性）
            var file = files[0];
            if (file == null || file.Length == 0)
                throw Oops.Bah("请选择有效的图片文件");

            try
            {
                // 图片重命名 拼接 type + wareCode + 原文件名后缀（保留格式）
                var originalExt = Path.GetExtension(file.FileName);
                var fileFileName = $"{Guid.NewGuid()}{originalExt}";

                using var stream = file.OpenReadStream();

                // 调用接口时，使用简化模型接收响应
                var response = await new FlurlRequest("https://api.imgbb.com/1/upload")
                    .PostMultipartAsync(mp => mp
                        .AddString("key", _apiKey)
                        .AddFile("image", stream, fileFileName))
                    .ReceiveJson<ImgBBResponse>();

                // 直接获取需要的 url
                if (response?.success == true && response.data != null)
                {
                    string imageUrl = response.data.url; // 只使用这个字段
                                                         // 后续逻辑...
                    return response;
                }
                else
                {
                    throw Oops.Bah("图片上传失败");
                }
            }
            catch (FlurlHttpException ex)
            {
                throw Oops.Bah("图片上传失败", ex);
            }
        }


    }
}
